package com.uinnova.product.eam.service.asset.impl;

import com.binary.core.exception.BinaryException;
import com.binary.core.util.BinaryUtils;
import com.uinnova.product.eam.comm.bean.CcCiAttrDefGroupConfVO;
import com.uinnova.product.eam.comm.bean.CcCiAttrDefTapGroupConfVO;
import com.uinnova.product.eam.comm.bean.CcCiClassInfoConfVO;
import com.uinnova.product.eam.comm.model.es.AppSquareConfig;
import com.uinnova.product.eam.comm.model.es.AssetDetailAttrConf;
import com.uinnova.product.eam.service.AppSquareConfigSvc;
import com.uinnova.product.eam.service.IEamCIClassApiSvc;
import com.uinnova.product.eam.service.asset.AssetDetailAttrConfSvc;
import com.uinnova.product.eam.service.es.AssetDetailAttrConfDao;
import com.uinnova.product.vmdb.comm.model.ci.CcCiAttrDef;
import com.uinnova.product.vmdb.provider.ci.bean.CcCiClassInfo;
import com.uino.bean.permission.base.SysUser;
import com.uino.util.sys.BeanUtil;
import com.uino.util.sys.SysUtil;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author zdh_c
 */
@Service
public class AssetDetailAttrConfSvcImpl implements AssetDetailAttrConfSvc {

    public static final String APP_SQUARE_CONF_ID = "appSquareConfId";
    public static final String DOMAIN_ID = "domainId";
    @Resource
    AssetDetailAttrConfDao detailAttrConfDao;

    @Resource
    IEamCIClassApiSvc ciClassApiSvc;

    @Resource
    AppSquareConfigSvc appSquareConfigSvc;


    @Override
    public Long saveOrUpdateDetailAttr(AssetDetailAttrConf target) {
        if (BinaryUtils.isEmpty(target.getClassCode())) {
            throw new BinaryException("分类标识不可为空");
        }
        if (BinaryUtils.isEmpty(target.getAppSquareConfId())) {
            throw new BinaryException("广场卡片ID不可为空");
        }
        SysUser currentUserInfo = SysUtil.getCurrentUserInfo();
        String loginCode = currentUserInfo.getLoginCode();
        Long domainId = currentUserInfo.getDomainId();
        BoolQueryBuilder query = QueryBuilders.boolQuery();
        query.must(QueryBuilders.termQuery(APP_SQUARE_CONF_ID, target.getAppSquareConfId()));
        query.must(QueryBuilders.termQuery(DOMAIN_ID, domainId));
        if (!BinaryUtils.isEmpty(target.getId())) {
            query.mustNot(QueryBuilders.termQuery("id", target.getId()));
        }
        AssetDetailAttrConf attrConf = detailAttrConfDao.selectOne(query);
        if (!BinaryUtils.isEmpty(attrConf)) {
            throw new BinaryException("该卡片详情配置已存在");
        }
        target.setDomainId(domainId);
        long timeMillis = System.currentTimeMillis();
        if (BinaryUtils.isEmpty(target.getId())) {
            target.setCreator(loginCode);
            target.setCreateTime(timeMillis);
        } else {
            target.setModifier(loginCode);
            target.setModifyTime(timeMillis);
        }
        // 必填项添加入其他字段
        CcCiClassInfo classInfo = ciClassApiSvc.queryClassAndAttrMappingByCode(target.getClassCode());
        Map<Long, CcCiAttrDef> attrDefMap = classInfo.getAttrDefs().stream()
                .filter(ccCiAttrDef -> !BinaryUtils.isEmpty(ccCiAttrDef.getIsRequired()) && ccCiAttrDef.getIsRequired().equals(1))
                .collect(Collectors.toMap(CcCiAttrDef::getId, ccCiAttrDef -> ccCiAttrDef, (k1, k2) -> k1));
        List<CcCiAttrDefTapGroupConfVO> showAttrs = target.getShowAttrs();
        List<Long> attrShowIds = new ArrayList<>();
        if (!CollectionUtils.isEmpty(showAttrs)) {
            for (CcCiAttrDefTapGroupConfVO showAttr : showAttrs) {
                List<CcCiAttrDefGroupConfVO> tapAttr = showAttr.getTapAttr();
                if (!CollectionUtils.isEmpty(tapAttr)) {
                    for (CcCiAttrDefGroupConfVO attrDefGroup : tapAttr) {
                        List<CcCiAttrDef> ccCiAttrDefs = attrDefGroup.getAttrDefs();
                        for (CcCiAttrDef ccCiAttrDef : ccCiAttrDefs) {
                            attrShowIds.add(ccCiAttrDef.getId());
                        }
                    }
                }
            }
        }
        for (Long attrShowId : attrShowIds) {
            if (attrDefMap.containsKey(attrShowId)) {
                attrDefMap.remove(attrShowId);
            }
        }
        if (!CollectionUtils.isEmpty(attrDefMap)) {
            CcCiAttrDefTapGroupConfVO firstTab = showAttrs.get(0);
            if (!BinaryUtils.isEmpty(firstTab)) {
                List<CcCiAttrDefGroupConfVO> tapAttr = firstTab.getTapAttr();
                CcCiAttrDefGroupConfVO otherAttrTab = new CcCiAttrDefGroupConfVO();
                otherAttrTab.setName("其他字段");
                List<CcCiAttrDef> ccCiAttrDefs = new ArrayList<>();
                otherAttrTab.setAttrDefs(ccCiAttrDefs);
                for (Long otherAttrId : attrDefMap.keySet()) {
                    CcCiAttrDef attrDef = new CcCiAttrDef();
                    attrDef.setId(otherAttrId);
                    ccCiAttrDefs.add(attrDef);
                }
                tapAttr.add(otherAttrTab);
            }
        }
        return detailAttrConfDao.saveOrUpdate(target);
    }

    @Override
    public AssetDetailAttrConf getDetailAttr(Long appSquareConfId) {
        if (BinaryUtils.isEmpty(appSquareConfId)) {
            throw new BinaryException("资产卡片配置ID不可为空");
        }
        SysUser currentUserInfo = SysUtil.getCurrentUserInfo();
        Long domainId = currentUserInfo.getDomainId();
        BoolQueryBuilder query = QueryBuilders.boolQuery();
        query.must(QueryBuilders.termQuery(APP_SQUARE_CONF_ID, appSquareConfId));
        query.must(QueryBuilders.termQuery(DOMAIN_ID, domainId));
        return detailAttrConfDao.selectOne(query);
    }

    @Override
    public Integer deleteDetailAttrById(Long id) {
        return detailAttrConfDao.deleteById(id);
    }

    @Override
    public Integer deleteDetailAttrByAppSquareConfId(Long appSquareConfId) {
        BoolQueryBuilder query = QueryBuilders.boolQuery();
        query.must(QueryBuilders.termQuery(APP_SQUARE_CONF_ID, appSquareConfId));
        query.must(QueryBuilders.termQuery(DOMAIN_ID, SysUtil.getCurrentUserInfo().getDomainId()));
        return detailAttrConfDao.deleteByQuery(query, true);
    }

    @Override
    public CcCiClassInfoConfVO getClassInfoDetailAttr(Long appSquareConfId) {
        CcCiClassInfoConfVO classInfoConf = new CcCiClassInfoConfVO();
        AssetDetailAttrConf detailAttr = getDetailAttr(appSquareConfId);
        if (BinaryUtils.isEmpty(detailAttr)) {
            return classInfoConf;
        }
        String classCode = detailAttr.getClassCode();
        CcCiClassInfo classInfo = ciClassApiSvc.queryClassAndAttrMappingByCode(classCode);
        BinaryUtils.checkEmpty(classInfo, "分类信息");
        BeanUtil.copyProperties(classInfo, classInfoConf);
        List<CcCiAttrDef> attrDefs = classInfo.getAttrDefs();
        Map<Long, CcCiAttrDef> attrDefMap = attrDefs.stream().collect(Collectors.toMap(CcCiAttrDef::getId, e -> e, (k1, k2) -> k1));

        List<CcCiAttrDefTapGroupConfVO> showAttrs = detailAttr.getShowAttrs();
        for (CcCiAttrDefTapGroupConfVO showAttr : showAttrs) {
            // tab页
            if (!BinaryUtils.isEmpty(showAttr.getTapAttr())) {
                for (CcCiAttrDefGroupConfVO groupConfVO : showAttr.getTapAttr()) {
                    // 区域
                    List<CcCiAttrDef> ccCiAttrDefs = new ArrayList<>();
                    if (!BinaryUtils.isEmpty(groupConfVO.getAttrDefs())) {
                        for (CcCiAttrDef ccCiAttrDef : groupConfVO.getAttrDefs()) {
                            CcCiAttrDef attrDef = attrDefMap.get(ccCiAttrDef.getId());
                            if (!BinaryUtils.isEmpty(attrDef)) {
                                ccCiAttrDefs.add(attrDef);
                            }
                        }
                    }
                    groupConfVO.setAttrDefs(ccCiAttrDefs);
                }
            }
        }
        classInfoConf.setShowDetailCIAttrInfo(showAttrs);
        return classInfoConf;
    }

    @Override
    public Map<String, AppSquareConfig> getAppSquareByClassCode(List<String> classCodes) {
        if (CollectionUtils.isEmpty(classCodes)) {
            return Collections.emptyMap();
        }
        List<AssetDetailAttrConf> detailAttrConfList = detailAttrConfDao.getListByQuery(QueryBuilders.termsQuery("classCode.keyword", classCodes));
        List<Long> appSquareIds = detailAttrConfList.stream().map(AssetDetailAttrConf::getAppSquareConfId).collect(Collectors.toList());
        List<AppSquareConfig> appSquareConfigs = appSquareConfigSvc.getListInfoByIds(appSquareIds);
        return appSquareConfigs.stream()
                .collect(Collectors.toMap(AppSquareConfig::getClassCode, e->e, (k1, k2) -> k1));
    }

    @Override
    public Map<String, AssetDetailAttrConf> getAssetConfigMap(List<String> classCodes) {
        if (CollectionUtils.isEmpty(classCodes)) {
            return Collections.emptyMap();
        }
        List<AssetDetailAttrConf> confList = detailAttrConfDao.getListByQuery(QueryBuilders.termsQuery("classCode.keyword", classCodes));
        if(CollectionUtils.isEmpty(confList)){
            return Collections.emptyMap();
        }
        return confList.stream().collect(Collectors.toMap(AssetDetailAttrConf::getClassCode, e->e, (k1, k2)->k2));
    }
}
